WD PLUS 2020-11 (dashboard)
7. Struktury danych - tablice i obiekty (Moduł)
7.4. Szablony Handlebars
Zadanie: Wykorzystanie szablonów w projekcie
Czas użyć szablonów HTML w naszym blogu!
Skrypt, który do tej pory napisaliśmy, generuje fragmenty kodu HTML w pięciu miejscach:
- dla linka do artykułu, umieszczanego w lewej kolumnie,
- dla linka do tagu, umieszczanego na końcu każdego artykułu,
- dla linka do autora, umieszczanego pod tytułem każdego artykułu,
- dla linka do tagu, umieszczanego w chmurze tagów w prawej kolumnie,
- dla linka do autora, umieszczanego na liście w prawej kolumnie.
Dla pozycji 1-3 zastosuj szablony pojedynczego linka, czyli wedle przykładu wykorzystującego tplHello.
Dla pozycji 4-5 zastosuj szablony zawierające pętlę. Aby je wykorzystać, w swoim kodzie musisz odnaleźć miejsca, w których generujesz kod tych linków. Zamiast generować kod, stwórz obiekt i wypełniaj go danymi w takiej strukturze, jakiej będzie wymagał szablon.
Handlebars a ESLint
ESLint domyślnie zakłada, że elementy, które znajdują się poza danym plikiem, nie mogą być w nim użyte, dopóki ich nie zaimportujemy (np. przy użyciu instrukcji import). Nie bierze jednak pod uwagę, że dodając do pliku HTML kilka plików JS przy użyciu tagu <script>, mogą one korzystać nawzajem ze swojej zawartości i wtedy wcale nie musimy niczego importować. Na przykład, gdy dodamy do index.html informację o a.js i b.js, w tym drugim pliku będziemy mogli korzystać z pierwszego bez żadnych problemów.
Tym samym może dojść do sytuacji, w której Twój kod działa poprawnie, a jednak ESLint wyrzuca błąd mówiący, że Handlebars są niezdefiniowane. Możemy jednak łatwo to naprawić. Wystarczy poinformować ESLint, że jest to coś globalnego i powinien zakładać, że każdy plik JS ma do niego dostęp. Możesz to zrobić, dodając do pliku eslintrc.json regułę:
"globals": {
"Handlebars": false
}
Jak zastosować Handlebars w projekcie?
Zaczynamy od dodania skryptu Handlebars. W kodzie HTML znajdź tę linię kodu:
<script src="js/script.js"></script>
I nad nią umieść tę linię:
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.1.0/handlebars.min.js"></script>
Ten skrypt dodajemy tylko raz, niezależnie od tego ilu szablonów będziemy używać.
Teraz przed tą linią wstaw swój pierwszy szablon:
<script id="template-article-link" type="text/x-handlebars-template">
<li><a href="#{{ id }}"><span>{{ title }}</span></a></li>
</script>
Następnie na początku swojego pliku JS wstaw ten kod:
const templates = {
articleLink: Handlebars.compile(document.querySelector('#template-article-link').innerHTML)
}
Dodając później kolejne szablony, będziesz rozbudowywać obiekt templates, aby wszystkie mieć zebrane w jednym miejscu. Wystarczy, że skopiujesz tę linię i zmienisz klucz articleLink i selektor #template-article-link.
Kolejnym krokiem jest wykorzystanie szablonu – zacznij od znalezienia tej linii kodu:
const linkHTML = '<li><a href="#' + articleId + '"><span>' + articleTitle + '</span></a></li>';
Zamień ją na następującą:
const linkHTMLData = {id: articleId, title: articleTitle};
const linkHTML = templates.articleLink(linkHTMLData);
W ten sposób wykonaliśmy pkt. 1 tego zadania. Punkty 2 i 3 wykonaj, powtarzając te same kroki.
Dla punktów 4 i 5 będzie odrobinę trudniej. Omówmy sobie pokrótce wykonanie pkt. 4.
1. Zacznij od dodania pustego szablonu w kodzie HTML oraz w obiekcie templates. Założymy, że ten szablon będzie miał klucz tagCloudLink, czyli będziemy go używać jako templates.tagCloudLink.
2. Najpierw znajdujesz let allTagsHTML = ''; – to zmienna, w której przechowujemy kod HTML wszystkich linków do tagów. Nie będzie już nam potrzebna, a zamiast niej chcemy mieć:
const allTagsData = {tags: []};
3. Następnie znajdujemy linię allTagsHTML += tagLinkHTML;. Ta linia doklejała kod kolejnego linka do allTagsHTML. Zamiast tego, chcemy do tablicy allTagsHTML dodawać kolejny obiekt, np.:
allTagsData.tags.push({
tag: tag,
count: allTags[tag],
className: calculateTagClass(allTags[tag], tagsParams)
});
4. Teraz znajdujemy linię tagList.innerHTML = allTagsHTML; – nie mamy już allTagsHTML, więc zamieniamy tę linię na:
tagList.innerHTML = templates.tagCloudLink(allTagsData);
To jest też dobre miejsce, aby za pomocą console.log sprawdzić, jak wygląda zawartość allTagsData.
5. Wszystko powinno działać, ale do tej pory nasz szablon był pusty. Zacznij od wstawienia w nim jakiegoś tekstu, aby sprawdzić, czy ten tekst wyświetli się tylko raz na stronie. Jeśli tak, wszystko działa poprawnie. Teraz w naszym szablonie potrzebujemy zrobić pętlę. Zacznij od takiego szablonu:
<script id="template-tag-cloud-link" type="text/x-handlebars-template">
{{#each tags}}
<li>{{ tag }}</li>
{{/each}}
</script>
Na stronie, w prawej kolumnie, powinna pojawić się lista tagów. Nie są one jednak jeszcze linkami, i nie mają klas odpowiedzialnych za rozmiar tagu. Aby sobie z tym poradzić, użyj właściwości count i className w swoim szablonie.
Dokończenie zadania
Reszta rozwiązania będzie bardzo podobna do powyższych kroków. Nie bój się eksperymentować i używać console.log do sprawdzania, czy jesteś na dobrym tropie.
Dzięki tym zmianom cały kod HTML znajdzie się pliku HTML, a nasz kod JS będzie korzystał z szablonów. To bardzo przydatna umiejętność, którą będziemy wykorzystywać w kolejnych modułach.